import 'dart:convert';
import 'dart:math';

import 'package:crypto/crypto.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_widgets_pc/utils/ex/kq_ex.dart';
import 'package:intl/intl.dart';
import 'package:uuid/uuid.dart';

/// 字符串辅助类
class StrUtil {
  /// 判断字符串、集合、字典是否为空
  static bool isEmpty(dynamic obj) {
    if (obj is String) {
      return obj.isEmpty;
    }
    if (obj is Map) {
      return obj.isEmpty;
    }
    if (obj is Iterable) {
      return obj.isEmpty;
    }
    return obj == null;
  }

  /// 生成uuid
  static String uuid() {
    var uuid = const Uuid();
    return uuid.v4();
  }

  /// md5加密
  static String md5Crypto(String str) {
    var bytes = utf8.encode(str);
    final dig = md5.convert(bytes);
    var keyStr = dig.toString();
    return keyStr;
  }

  /// 获取指定长度的随机字母字符串
  static String getRandomStr(int length) {
    String alphabet = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
    String left = "";
    for (var i = 0; i < length; i++) {
      left = left + alphabet[Random().nextInt(alphabet.length)];
    }
    return left;
  }

  /// 获取GMT格式时间
  static String getGMTDateString() {
    var date = DateTime.now();
    date = date.subtract(const Duration(hours: 8));
    return DateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", 'en').format(date);
  }

  /// 格式化日期 yyyy-mm
  static String formatDatetimeYM(DateTime dateTime, {String split = '-'}) {
    return formatDate(dateTime, [yyyy, split, mm]);
  }

  /// 格式化日期 yyyy-mm-dd
  static String formatDatetimeYMD(DateTime dateTime, {String split = '-'}) {
    return formatDate(dateTime, [yyyy, split, mm, split, dd]);
  }

  /// 格式化日期和小时 yyyy-MM-dd HH
  static String formatDatetimeYMDH(
    DateTime dateTime, {
    String dateSplit = '-',
    String hourUnit = '',
    bool widthSpace = true,
  }) {
    return formatDate(dateTime, [
      yyyy,
      dateSplit,
      mm,
      dateSplit,
      dd,
      widthSpace ? ' ' : '',
      HH,
      hourUnit
    ]);
  }

  /// 格式化时间 HH:mm
  static String formatDatetimeHm(DateTime dateTime, {String split = ':'}) {
    return formatDate(dateTime, [HH, split, nn]);
  }

  /// 格式化时间 HH:mm:ss
  static String formatDatetimeHms(DateTime dateTime, {String split = ':'}) {
    return formatDate(dateTime, [HH, split, nn, split, ss]);
  }

  /// 格式化日期和时间 yyyy-MM-dd HH:mm
  static String formatDatetimeYMDHm(DateTime dateTime, {String split = '-'}) {
    return formatDate(dateTime, [yyyy, split, mm, split, dd, ' ', HH, ':', nn]);
  }

  /// 格式化日期和时间 yyyy-MM-dd HH:mm:ss
  static String formatDatetimeYMDHms(DateTime dateTime,
      {String dateSplit = '-', String timeSplit = ':'}) {
    return formatDate(dateTime, [
      yyyy,
      dateSplit,
      mm,
      dateSplit,
      dd,
      ' ',
      HH,
      timeSplit,
      nn,
      timeSplit,
      ss
    ]);
  }

  ///判断是否是整数
  ///isPositive是否是正数
  static bool isNumber(String? str, {bool isPositive = false}) {
    if (str == null || str == '' || str.startsWith('.')) {
      return false;
    }
    if (isPositive) {
      if (str.startsWith('-')) {
        return double.tryParse(str) != null;
      }
      return false;
    }
    return double.tryParse(str) != null;
  }

  /// 动态拼接数据
  /// [concatWhenEmpty] 为空时是否拼接
  static String? concatDynamic<T>(
      List<T>? list, String? Function(T t) concatConverter,
      {String split = ',',
        String? defaultValue,
        bool concatWhenEmpty = false}) {
    if (list == null) {
      return defaultValue;
    }
    String str = '';
    for (var value in list) {
      if (str.isEmpty) {
        str = concatConverter(value) ?? '';
      } else {
        str = concatString(str, concatConverter(value), split,
            concatWhenEmpty: concatWhenEmpty);
      }
    }
    return str.isEmpty ? defaultValue : str;
  }


  /// 拼接字符串，中间使用[split]分割，如果有一个字符串为空，则不显示[split]
  /// [concatWhenEmpty] 为空时是否拼接
  static String concatString(String? str1, String? str2, String split,
      {bool concatWhenEmpty = false}) {
    if (str1.isNullOrEmpty) {
      if (concatWhenEmpty) {
        return '$split${str2 ?? ''}';
      } else {
        return str2 ?? '';
      }
    }
    if (str2.isNullOrEmpty) {
      if (concatWhenEmpty) {
        return '$str1$split';
      } else {
        return str1!;
      }
    }
    return '$str1$split$str2';
  }

  /// 获取列表数据中的单个指定key列表
  static List<V> concatValueToList<V, T>(
      List<T>? list, V Function(T t) concatConverter) {
    List<V> rList = [];
    if (list == null) {
      return rList;
    }
    for (T t in list) {
      rList.add(concatConverter(t));
    }
    return rList;
  }

  ///类型判断
  static T? getValue<T>(var value) {
    if (value == null) {
      return null;
    } else if (T == bool) {
      return ((value == true) || (value == "1") || (value == "true")) as T;
    } else if (T == String) {
      return value as T;
    } else if (T == int) {
      if (value is int) {
        return value as T;
      } else {
        return int.tryParse('$value') as T?;
      }
    } else if (T == double) {
      if (value is double) {
        return value as T;
      } else {
        return double.tryParse('$value') as T?;
      }
    } else {
      return value;
    }
  }

}

/// 格式化工具
class StrFormatUtil {
  /// 自动格式化文章
  ///
  /// [content] 文章内容
  /// [emptyLine] 是否空行，默认true
  /// [autoIndent] 是否自动段首缩进2字符，默认true
  /// [autoChEnSpace] 是否自动在中文和其他字符(数字/英文)之间添加空格(盘古之白)，默认true
  static String autoFormat(String? content,
      {bool emptyLine = true,
      bool autoIndent = true,
      bool autoChEnSpace = true}) {
    if (content == null) {
      return '';
    }
    //1. 拿到所有段落
    List<ParagraphEntity> list = [];
    List<String> allParagraph = content.split("\n");
    for (String paragraph in allParagraph) {
      if (paragraph.replaceAll("\u3000", "").trim().isNotEmpty) {
        list.add(ParagraphEntity(paragraph: paragraph));
      }
    }

    //2. 处理段落
    for (ParagraphEntity paragraph in list) {
      //(1)移除段首缩进
      String pg = paragraph.paragraph;
      String indent = getIndent(pg, 0, pg.length);
      if (indent.isNotEmpty) {
        paragraph.paragraph = pg.substring(indent.length);
      }
      //(2)添加段首缩进
      if (autoIndent) {
        String pg2 = paragraph.paragraph;
        paragraph.paragraph = "\u3000\u3000$pg2";
      }
      //(3)中英文之间插入空格
      if (autoChEnSpace) {
        //中英
        var regLeft = RegExp(r'([\u4e00-\u9fa5]+)([\da-zA-Z]+)');
        String pg3 = paragraph.paragraph;
        pg3 = pg3.replaceAllMapped(regLeft, (match) {
          var group0 = match.group(0) ?? '';
          var group1 = match.group(1) ?? '';
          group0 = group0.replaceAll(group1, '');
          return '$group1 $group0';
        });
        //英中
        var regRight = RegExp(r'([\da-zA-Z]+)([\u4e00-\u9fa5]+)');
        pg3 = pg3.replaceAllMapped(regRight, (match) {
          var group0 = match.group(0) ?? '';
          var group1 = match.group(1) ?? '';
          group0 = group0.replaceAll(group1, '');
          return '$group1 $group0';
        });
        paragraph.paragraph = pg3;
      }
    }

    //拼接
    StringBuffer str = StringBuffer();
    for (int i = 0; i < list.length; i++) {
      ParagraphEntity paragraphEntity = list[i];
      str.write(paragraphEntity.paragraph);
      if (i != list.length - 1) {
        str.write("\n");
        //(3)添加空行
        if (emptyLine) {
          str.write("\n");
        }
      }
    }

    return str.toString();
  }

  /// 获取缩进
  static String getIndent(String s, int start, int end) {
    int mEnd = start;
    int whiteSpaceQty = 0;
    for (int i = start; i < end; i++) {
      String c = s.substring(i, i + 1);
      if (!isWhitespace(c) && c != '·') {
        mEnd = i;
        break;
      } else {
        whiteSpaceQty++;
      }
    }
    if (whiteSpaceQty == (end - start)) {
      mEnd = end;
    }
    if (mEnd > start) {
      return s.substring(start, mEnd);
    }
    return "";
  }

  static bool isWhitespace(String c) {
    return (c == ' ') ||
        (c == '\t') ||
        (c == String.fromCharCode(160)) ||
        (c == '\u3000');
  }

  /// 是不是成对符号
  static bool isPairChar(String? str) {
    if (str == null) {
      return false;
    }
    return str == "()" ||
        str == "''" ||
        str == "“”" ||
        str == "\"\"" ||
        str == "（）" ||
        str == "[]" ||
        str == "「」" ||
        str == "{}" ||
        str == "｛｝" ||
        str == "【】" ||
        str == "《》" ||
        str == "<>";
  }

  /// 是不是成对符号的右半边
  static bool isPairCharRight(String? str) {
    if (str == null) {
      return false;
    }
    return str == ")" ||
        str == "'" ||
        str == "”" ||
        str == "\"" ||
        str == "）" ||
        str == "]" ||
        str == "」" ||
        str == "}" ||
        str == "｝" ||
        str == "】" ||
        str == "》" ||
        str == ">";
  }

  /// 是不是成对符号的左半边
  static bool isPairCharLeft(String? str) {
    if (str == null) {
      return false;
    }
    return str == "(" ||
        str == "'" ||
        str == "“" ||
        str == "\"" ||
        str == "（" ||
        str == "[" ||
        str == "「" ||
        str == "{" ||
        str == "｛" ||
        str == "【" ||
        str == "《" ||
        str == "<";
  }
}

class ParagraphEntity {
  String paragraph;

  ParagraphEntity({required this.paragraph});
}
